package com.reverse.engineering.util.core.run.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String工具 主要对 StringUtils 的一些方法进行重写,达到更方便的使用
 * 
 * @author liu
 * @date 2020-08-06
 */
public class StringUtils extends org.apache.commons.lang.StringUtils {

    /**
     * 判断一个字符串是否是空
     * 
     * @param str
     * @return
     */
    public static boolean isBlank(String str) {
        return null == str || "".equals(str.trim()) || "null".equals(str.trim());
    }

    /**
     * 一次性判断多个或单个字符串是否有空
     * 
     * @param strs
     * @return 所有元素都为Blank,则返回true
     */
    public static boolean isBlankListAll(String... strs) {
        for (String string : strs) {
            if (isNotBlank(string)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 一次性判断多个或单个字符串是否有空
     * 
     * @param strs
     * @return 只要有一个元素为Blank,则返回true
     */
    public static boolean isBlankListOne(String... strs) {
        for (String string : strs) {
            if (isBlank(string)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断一个对象是否是空
     * 
     * @param obj
     * @return
     */
    public static boolean isBlankObject(Object obj) {
        return null == obj;
    }

    /**
     * 一次性判断多个或单个对象是否有空
     * 
     * @param objs
     * @return 所有元素都为Blank,则返回true
     */
    public static boolean isBlankObjectListAll(Object... objs) {
        for (Object object : objs) {
            if (isNotBlankObject(object)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 一次性判断多个或单个对象是否有空
     * 
     * @param objs
     * @return 只要有一个元素为Blank,则返回true
     */
    public static boolean isBlankObjectListOne(Object... objs) {
        for (Object object : objs) {
            if (isBlankObject(object)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断一个字符串是否不是空
     * 
     * @param str
     * @return
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 一次性判断多个或单个字符串不为空
     * 
     * @param strs
     * @return 所有元素都不为Blank,则返回true
     */
    public static boolean isNotBlankListAll(String... strs) {
        for (String string : strs) {
            if (isBlank(string)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 一次性判断多个或单个字符串不为空
     * 
     * @param strs
     * @return 只要有一个元素不为Blank,则返回true
     */
    public static boolean isNotBlankListOne(String... strs) {
        for (String string : strs) {
            if (isNotBlank(string)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断一个对象是否不是空
     * 
     * @param obj
     * @return
     */
    public static boolean isNotBlankObject(Object obj) {
        return !isBlankObject(obj);
    }

    /**
     * 一次性判断多个或单个对象不为空
     * 
     * @param objects
     * @return 所有元素都不为Blank,则返回true
     */
    public static boolean isNotBlankObjectListAll(Object... objs) {
        for (Object object : objs) {
            if (isBlankObject(object)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 一次性判断多个或单个对象不为空
     * 
     * @param objects
     * @return 只要有一个元素不为Blank,则返回true
     */
    public static boolean isNotBlankObjectListOne(Object... objs) {
        for (Object object : objs) {
            if (isNotBlankObject(object)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断两个对象是否一样(完全判断)
     * 
     * @param objOne
     * @param objTwo
     * @return
     */
    public static boolean equalsObject(Object objOne, Object objTwo) {
        return objOne.equals(objTwo) && objOne.hashCode() == objTwo.hashCode();
    }

    /**
     * 判断两个对象是否不一样(完全判断)
     * 
     * @param objOne
     * @param objTwo
     * @return
     */
    public static boolean notEqualsObject(Object objOne, Object objTwo) {
        return !equalsObject(objOne, objTwo);
    }

    /**
     * 判断字符串是否包含汉字
     * 
     * @param txt
     * @return
     */
    public static Boolean containsCN(String txt) {
        if (isBlank(txt)) {
            return false;
        }
        for (int i = 0; i < txt.length(); i++) {

            String bb = txt.substring(i, i + 1);

            boolean cc = java.util.regex.Pattern.matches("[\u4E00-\u9FA5]", bb);
            if (cc) {
                return cc;
            }
        }
        return false;
    }

    /**
     * 把Map转换成get请求参数类型,如 {"name"=20,"age"=30} 转换后变成 name=20&age=30
     * 
     * @param map
     * @return
     */
    public static String mapToGet(Map<? extends Object, ? extends Object> map) {
        String result = "";
        if (map == null || map.size() == 0) {
            return result;
        }
        Set<? extends Object> keys = map.keySet();
        for (Object key : keys) {
            result += ((String)key + "=" + (String)map.get(key) + "&");
        }

        return isBlank(result) ? result : result.substring(0, result.length() - 1);
    }

    /**
     * 把一串参数字符串,转换成Map 如"?a=3&b=4" 转换为Map{a=3,b=4}
     * 
     * @param args
     * @return
     */
    public static Map<String, ? extends Object> getToMap(String args) {
        if (isBlank(args)) {
            return null;
        }
        args = args.trim();
        // 如果是?开头,把?去掉
        if (args.startsWith("?")) {
            args = args.substring(1, args.length());
        }
        String[] argsArray = args.split("&");

        Map<String, Object> result = new HashMap<>();
        for (String ag : argsArray) {
            if (!isBlank(ag) && ag.indexOf("=") > 0) {

                String[] keyValue = ag.split("=");
                // 如果value或者key值里包含 "="号,以第一个"="号为主 ,如 name=0=3 转换后,{"name":"0=3"}, 如果不满足需求,请勿修改,自行解决.

                String key = keyValue[0];
                String value = "";
                for (int i = 1; i < keyValue.length; i++) {
                    value += keyValue[i] + "=";
                }
                value = value.length() > 0 ? value.substring(0, value.length() - 1) : value;
                result.put(key, value);

            }
        }
        return result;
    }

    /**
     * 去掉HTML代码
     * 
     * @param news
     * @return
     */
    public static String removeHtml(String news) {
        String s = news.replaceAll("amp;", "").replaceAll("<", "<").replaceAll(">", ">");

        Pattern pattern = Pattern.compile("<(span)?\\sstyle.*?style>|(span)?\\sstyle=.*?>", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(s);
        String str = matcher.replaceAll("");

        Pattern pattern2 = Pattern.compile("(<[^>]+>)", Pattern.DOTALL);
        Matcher matcher2 = pattern2.matcher(str);
        String strhttp = matcher2.replaceAll(" ");

        String regEx = "(((http|https|ftp)(\\s)*((\\:)|:))(\\s)*(//|//)(\\s)*)?"
            + "([\\sa-zA-Z0-9(\\.|．)(\\s)*\\-]+((\\:)|(:)[\\sa-zA-Z0-9(\\.|．)&%\\$\\-]+)*@(\\s)*)?" + "("
            + "(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])"
            + "(\\.|．)(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)"
            + "(\\.|．)(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)"
            + "(\\.|．)(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])"
            + "|([\\sa-zA-Z0-9\\-]+(\\.|．)(\\s)*)*[\\sa-zA-Z0-9\\-]+(\\.|．)(\\s)*[\\sa-zA-Z]*" + ")"
            + "((\\s)*(\\:)|(:)(\\s)*[0-9]+)?" + "(/(\\s)*[^/][\\sa-zA-Z0-9\\.\\,\\?\\'\\\\/\\+&%\\$\\=~_\\-@]*)*";
        Pattern p1 = Pattern.compile(regEx, Pattern.DOTALL);
        Matcher matchhttp = p1.matcher(strhttp);
        String strnew = matchhttp.replaceAll("").replaceAll("(if[\\s]*\\(|else|elseif[\\s]*\\().*?;", " ");

        Pattern patterncomma = Pattern.compile("(&[^;]+;)", Pattern.DOTALL);
        Matcher matchercomma = patterncomma.matcher(strnew);
        String strout = matchercomma.replaceAll(" ");
        String answer = strout.replaceAll("[\\pP‘’“”]", " ").replaceAll("\r", " ").replaceAll("\n", " ")
            .replaceAll("\\s", " ").replaceAll("　", "");

        return answer;
    }

    /**
     * 把数组的空数据去掉
     * 
     * @param array
     * @return
     */
    public static List<String> array2Empty(String[] array) {
        List<String> list = new ArrayList<>();
        for (String string : array) {
            if (StringUtils.isNotBlank(string)) {
                list.add(string);
            }
        }
        return list;
    }

    /**
     * serializable toString
     * 
     * @param serializable
     * @return
     */
    public static String toString(Serializable serializable) {
        if (null == serializable) {
            return null;
        }
        try {
            return (String)serializable;
        } catch (Exception e) {
            return serializable.toString();
        }
    }

}